/*
 * <one line to give the program's name and a brief idea of what it does.>
 * Copyright (C) 2019
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef DATA_H
#define DATA_H

#include "commonenum.hpp"
#include <cstdint>

#include <iostream>

/**
 * \file commondata.hpp
 * \brief contain basic structs
 *
 * Add struct definitions for resource, build, player state, battle stats
 */

/**
 * \struct resource
 * \brief resource struct
 *
 * This is struct for resources using in game
 * \todo TODO check operators!
 */
struct resource {
	uint32_t imatter = 0;									/**< amount of I-Matter */
	uint32_t pcore = 0;										/**< amount of P-Cores */
	uint32_t ultium = 0;									/**< amount of Ultium */

	bool operator ==(const resource & other) const {
		return imatter == other.imatter && pcore == other.pcore && ultium == other.ultium;
	}

	bool operator >=(const resource & other) const {
		return imatter >= other.imatter && pcore >= other.pcore && ultium >= other.ultium;
	}

	// NOTE do not check pcore! for this
	// TODO we need this? is this correct?
	bool operator <(const resource & other) const {
		return imatter < other.imatter || ultium < other.ultium;
	}

	resource & operator =(const resource & other) {
		imatter = other.imatter;
		ultium = other.ultium;
		pcore = other.pcore;
		return *this;
	}

	resource & operator +=(const resource & other) {
		imatter += other.imatter;
		pcore += other.pcore;
		ultium += other.ultium;
		return *this;
	}

	resource & operator -=(const resource & other) {
		imatter -= other.imatter;
		pcore -= other.pcore;
		ultium -= other.ultium;
		return *this;
	}

};

/**
 * \struct ShipData
 * \brief ship data
 *
 * This is struct for battle statistic per ship. Describe ship status
 */
struct ShipData {
	double hp = 0;											/**< current ship hp */
	double hpMax = 0;										/**< max ship hp, leech and regeneration can't break this limit */
	double damage = 0;										/**< ship damage */
	double shield = 0;										/**< current ship shield */
	double reflection = 0;									/**< % of dmg will be reflected to attacker */
	double shieldAbsorption = 1;							/**< how much dmg can be absorpted by 1 shield */
	double shieldPenetration = 1;							/**< how many damage done do enemy shield */
	double leech = 0;										/**< how many % of damage will be converted to attacker hp */
	double regeneration = 0;								/**< how many % of hpMax will be recovered every turn */
	double deadly = 0;										/**< how much % will be added to damage with death of every ship */
	bool alive = true;										/**< is ship alive and can fight */
};

/**
 * \struct TrophyUpgrade
 */
struct TrophyUpgrade {
	uint8_t damage = 0;
	uint8_t hp = 0;
};

/**
 * \struct PlayerBuild
 * \brief ships build
 *
 * Contain ship build.
 * Each build have upgradeCount params, 4 params per ship
 * \todo TODO определиться с типами. и описать как что где хранится
 *
 */
struct PlayerBuild {
	uint16_t data[upgradeCount] = {};
};

/**
 * \struct PathData
 * Contain data for path creation
 * We need store ships build, max/min ai level and resources
 */
struct PathData {
	PlayerBuild ship;
	uint16_t ai[2] = {};
	uint32_t imatter = 0;
	uint32_t ultium = 0;
};

// for spdlog
std::ostream & operator<<(std::ostream & os, const PathData & build);

/**
 * \struct PlayerData
 * \brief player data
 *
 * This is struct for describe player data.
 * Contains all params, needed for battle simulation
 * Using for import or export
 * \todo TODO очки трофеи?
 */
struct PlayerData {
	uint8_t orbStars = 0;									/**< ship arena orb stars */
	uint8_t orbLevel = 0;									/**< ship arena orb levels */
	uint32_t virtue = 0;									/**< virtue level */
	double orbValue = 1;									/**< orb multiplier, based by orbStart and orbLevel and virtue */

	double guild = 1;										/**< guild multiplier for hp and dmg */
	double guildPassive = 1;								/**< guild passive multiplier for dmg */

	uint8_t legendary = 0;									/**< legendary dmg upgrade level */
	uint8_t ascDamage = 0;									/**< asc. dmg upgrade level */
	uint8_t ascHp = 0;										/**< asc. hp upgrade level */
	uint8_t trophyDamage = 0;								/**< trophy damage upgrade level */
	uint8_t trophyHp = 0;									/**< trophy hp upgrade level */

	resource resBase;										/**< total resources we have */
	resource resUpgrade;									/**< how many resources we have for upgrades */
	resource resHand;										/**< how many resources we have on hand */

	PlayerBuild buildBase;									/**< baseline ships build */
	PlayerBuild buildTest;									/**< test ships build, can be used as limit */

	uint8_t drones[5] = {0};								/**< drone levels */
	droneType droneTypes[5];								/**< drone types */

	uint16_t aiBase = 1;									//*< baseline ai level */
	uint16_t aiTest = 1;									//*< test ai level, can be used as limit */

	//! temp data, idk what i must do with that yet
// 	uint32_t trophyPointBase;								//! how many trophy points we have
// 	uint32_t trophyPointTest;								//! without ship power
};


#endif // DATA_H
